docs: Fix inclusion of source files in tutorial
authorMohammed Sadiq <sadiq@sadiqpk.org>
Mon, 17 Sep 2018 08:07:43 +0000 (13:37 +0530)
committerMohammed Sadiq <sadiq@sadiqpk.org>
Mon, 17 Sep 2018 08:09:22 +0000 (13:39 +0530)
docs/reference/gtk/getting_started.xml [deleted file]
docs/reference/gtk/getting_started.xml.in [new file with mode: 0644]
docs/reference/gtk/meson.build
docs/reference/meson.build

diff --git a/docs/reference/gtk/getting_started.xml b/docs/reference/gtk/getting_started.xml
deleted file mode 100644 (file)
index 1808513..0000000
+++ /dev/null
@@ -1,1081 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
-               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
-]>
-<chapter id="gtk-getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
-  <title>Getting Started with GTK+</title>
-
-  <para>GTK+ is a <ulink url="http://en.wikipedia.org/wiki/Widget_toolkit">
-  widget toolkit</ulink>. Each user interface created by 
-  GTK+ consists of widgets. This is implemented in C using 
-  <link linkend="gobject">GObject</link>, an object-oriented framework for C.
-  Widgets are organized in a hierachy. The window widget is the main container.
-  The user interface is then built by adding buttons, drop-down menus, input 
-  fields, and other widgets to the window.
-  If you are creating complex user interfaces it is recommended to
-  use #GtkBuilder and its GTK-specific markup description language, instead of
-  assembling the interface manually. You can also use a visual user interface
-  editor, like <ulink url="https://glade.gnome.org/">Glade</ulink>.</para>
-  
-  <para>GTK+ is event-driven. The toolkit listens for events such as
-  a click on a button, and passes the event to your application.</para>
-
-  <para>This chapter contains some tutorial information to get you
-  started with GTK+ programming. It assumes that you have GTK+, its
-  dependencies and a C compiler installed and ready to use. If you
-  need to build GTK+ itself first, refer to the
-  <link linkend="gtk-compiling">Compiling the GTK+ libraries</link>
-  section in this reference.</para>
-
-  <section>
-    <title>Basics</title>
-
-    <para>To begin our introduction to GTK, we'll start with a simple
-    signal-based Gtk application. This program will create an empty 200 × 200 pixel
-    window.</para>
-
-    <informalfigure>
-      <mediaobject>
-        <imageobject>
-          <imagedata fileref="window-default.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-    </informalfigure>
-
-    <informalexample>
-      <para>Create a new file with the following content named <filename>example-0.c.</filename></para>
-      <programlisting><xi:include href="../../../../examples/window-default.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-    </informalexample>
-
-    <para>
-      You can compile the program above with GCC using:
-      <literallayout>
-        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-0 example-0.c `pkg-config --libs gtk+-4.0`</literal>
-      </literallayout>
-    </para>
-
-    <note><para>For more information on how to compile a GTK+ application, please
-    refer to the <link linkend="gtk-compiling">Compiling GTK+ Applications</link>
-    section in this reference.</para></note>
-
-    <para>All GTK+ applications will, of course, include
-    <filename>gtk/gtk.h</filename>, which declares functions, types and
-    macros required by GTK+ applications.</para>
-
-    <warning><para>Even if GTK+ installs multiple header files, only the
-    top-level <filename>gtk/gtk.h</filename> header can be directly included
-    by third party code. The compiler will abort with an error if any other
-    header is directly included.</para></warning>
-
-    <para>In a GTK+ application, the purpose of the main() function is to
-    create a #GtkApplication object and run it. In this example a
-    #GtkApplication pointer named <varname>app</varname> is called and then
-    initialized using gtk_application_new().</para>
-
-    <para>When creating a #GtkApplication
-    you need to pick an application identifier (a name)
-    and input to gtk_application_new() as parameter.
-    For this example <varname>org.gtk.example</varname> is used
-    but for choosing an identifier for your application see
-    <ulink url="https://wiki.gnome.org/HowDoI/ChooseApplicationID">this guide</ulink>.
-    Lastly gtk_application_new() takes a GApplicationFlags as input for your 
-    application, if your application would have special needs.
-    </para>
-
-    <para>Next the
-    <ulink url="https://wiki.gnome.org/HowDoI/GtkApplication">activate signal</ulink>
-    is connected to the activate() function above the main() functions.
-    The <varname>activate</varname> signal will be sent
-    when your application is launched with
-    g_application_run() on the line below.
-    The gtk_application_run() also takes as arguments the pointers to the command line arguments
-    counter and string array; this allows GTK+ to parse specific command line
-    arguments that control the behavior of GTK+ itself. The parsed arguments
-    will be removed from the array, leaving the unrecognized ones for your
-    application to parse.
-    </para>
-
-    <para>Within g_application_run the activate() signal is sent and
-    we then proceed into the <function>activate</function>() function of the
-    application. Inside the activate() function we want to construct
-    our GTK window, so that a window is shown when the application
-    is launched. The call to gtk_application_window_new() will
-    create a new #GtkWindow and store it inside the
-    <varname>window</varname> pointer. The window will have a frame,
-    a title bar, and window controls depending on the platform.</para>
-
-    <para>A window title is set using gtk_window_set_title(). This function
-    takes a GtkWindow* pointer and a string as input. As our
-    <varname>window</varname> pointer is a GtkWidget pointer, we need to cast it
-    to GtkWindow*.
-    But instead of casting <varname>window</varname> via
-    <varname>(GtkWindow*)</varname>, 
-    <varname>window</varname> can be cast using the macro
-    <varname>GTK_WINDOW()</varname>.
-    <varname>GTK_WINDOW()</varname> will check if the 
-    pointer is an instance of the GtkWindow class, before casting, and emit a
-    warning if the check fails. More information about this convention 
-    can be found 
-    <ulink url="https://developer.gnome.org/gobject/stable/gtype-conventions.html">
-    here</ulink>.</para>
-
-    <para>Finally the window size is set using gtk_window_set_default_size and
-    the window is then shown by GTK via gtk_widget_show().</para>
-
-    <para>When you exit the window, by for example pressing the X,
-    the g_application_run() in the main loop returns with a number
-    which is saved inside an integer named "status". Afterwards, the
-    #GtkApplication object is freed from memory with g_object_unref().
-    Finally the status integer is returned and the GTK application exits.</para>
-
-    <para>While the program is running, GTK+ is receiving
-    <firstterm>events</firstterm>. These are typically input events caused by
-    the user interacting with your program, but also things like messages from
-    the window manager or other applications. GTK+ processes these and as a
-    result, <firstterm>signals</firstterm> may be emitted on your widgets.
-    Connecting handlers for these signals is how you normally make your
-    program do something in response to user input.</para>
-
-    <para>The following example is slightly more complex, and tries to
-    showcase some of the capabilities of GTK+.</para>
-
-    <para>In the long tradition of programming languages and libraries,
-    it is called <emphasis>Hello, World</emphasis>.</para>
-
-    <informalfigure>
-      <mediaobject>
-        <imageobject>
-          <imagedata fileref="hello-world.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-    </informalfigure>
-
-    <example id="gtk-getting-started-hello-world">
-      <title>Hello World in GTK+</title>
-      <para>Create a new file with the following content named example-1.c.</para>
-      <programlisting><xi:include href="../../../../examples/hello-world.c" parse="text">
-          <xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-    </example>
-
-    <para>
-      You can compile the program above with GCC using:
-      <literallayout>
-        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-1 example-1.c `pkg-config --libs gtk+-4.0`</literal>
-      </literallayout>
-    </para>
-  </section>
-
-  <para>As seen above, example-1.c builds further upon example-0.c by adding a
-  button to our window, with the label "Hello World". Two new GtkWidget pointers
-  are declared to accomplish this, <varname>button</varname> and
-  <varname>button_box</varname>. The button_box variable is created to store a
-  #GtkButtonBox which is GTK+'s way of controlling the size and layout of buttons.
-  The #GtkButtonBox is created and assigned to gtk_button_box_new() which takes a
-  #GtkOrientation enum as parameter. The buttons which this box will contain can
-  either be stored horizontally or vertically but this does not matter in this
-  particular case as we are dealing with only one button. After initializing
-  button_box with horizontal orientation, the code adds the button_box widget to the
-  window widget using gtk_container_add().</para>
-
-  <para>Next the <varname>button</varname> variable is initialized in similar manner.
-  gtk_button_new_with_label() is called which returns a GtkButton to be stored inside
-  <varname>button</varname>. Afterwards <varname>button</varname> is added to
-  our <varname>button_box</varname>.
-  Using g_signal_connect the button is connected to a function in our app called
-  print_hello(), so that when the button is clicked, GTK will call this function.
-  As the print_hello() function does not use any data as input, NULL is passed
-  to it. print_hello() calls g_print() with the string "Hello World"
-  which will print Hello World in a terminal if the GTK application was started
-  from one.</para>
-
-  <para>After connecting print_hello(), another signal is connected to the "clicked" state
-  of the button using g_signal_connect_swapped(). This functions is similar to
-  a g_signal_connect() with the difference lying in how the callback function is
-  treated. g_signal_connect_swapped() allow you to specify what the callback
-  function should take as parameter by letting you pass it as data. In this case
-  the function being called back is gtk_widget_destroy() and the <varname>window</varname>
-  pointer is passed to it. This has the effect that when the button is clicked,
-  the whole GTK window is destroyed. In contrast if a normal g_signal_connect() were used
-  to connect the "clicked" signal with gtk_widget_destroy(), then the <varname>button</varname>
-  itself would have been destroyed, not the window.
-  More information about creating buttons can be found
-  <ulink url="https://wiki.gnome.org/HowDoI/Buttons">here</ulink>.
-  </para>
-
-  <para>The rest of the code in example-1.c is identical to example-0.c. Next
-  section will elaborate further on how to add several GtkWidgets to your GTK
-  application.</para>
-
-  <section>
-    <title>Packing</title>
-
-    <para>When creating an application, you'll want to put more than one widget
-    inside a window.
-    When you want to put more than one widget into a window,
-    it becomes important to control how each widget is positioned and sized.
-    This is where packing comes in.</para>
-
-    <para>GTK+ comes with a large variety of <firstterm>layout containers</firstterm>
-    whose purpose it is to control the layout of the child widgets that are
-    added to them. See <xref linkend="LayoutContainers"/> for an overview.</para>
-
-    <para>The following example shows how the GtkGrid container lets you
-    arrange several buttons:</para>
-
-    <informalfigure>
-      <mediaobject>
-        <imageobject>
-          <imagedata fileref="grid-packing.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-    </informalfigure>
-
-    <example id="gtk-getting-started-grid-packing">
-      <title>Packing buttons</title>
-      <para>Create a new file with the following content named example-2.c.</para>
-      <programlisting><xi:include href="../../../../examples/grid-packing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-    </example>
-    <para>
-      You can compile the program above with GCC using:
-      <literallayout>
-        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-2 example-2.c `pkg-config --libs gtk+-4.0`</literal>
-      </literallayout>
-    </para>
-  </section>
-
-  <section>
-    <title>Building user interfaces</title>
-
-    <para>When construcing a more complicated user interface, with dozens
-    or hundreds of widgets, doing all the setup work in C code is
-    cumbersome, and making changes becomes next to impossible.</para>
-
-    <para>Thankfully, GTK+ supports the separation of user interface
-    layout from your business logic, by using UI descriptions in an
-    XML format that can be parsed by the #GtkBuilder class.</para>
-
-    <example>
-      <title>Packing buttons with GtkBuilder</title>
-      <para>Create a new file with the following content named example-3.c.</para>
-      <programlisting><xi:include href="../../../../examples/builder.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      <para>Create a new file with the following content named builder.ui.</para>
-      <programlisting><xi:include href="../../../../examples/builder.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-    </example>
-    <para>
-      You can compile the program above with GCC using:
-      <literallayout>
-        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-3 example-3.c `pkg-config --libs gtk+-4.0`</literal>
-      </literallayout>
-    </para>
-
-    <para>Note that GtkBuilder can also be used to construct objects
-    that are not widgets, such as tree models, adjustments, etc.
-    That is the reason the method we use here is called
-    gtk_builder_get_object() and returns a GObject* instead of a
-    GtkWidget*.</para>
-
-    <para>Normally, you would pass a full path to
-    gtk_builder_add_from_file() to make the execution of your program
-    independent of the current directory. A common location to install
-    UI descriptions and similar data is
-    <filename>/usr/share/<replaceable>appname</replaceable></filename>.
-    </para>
-
-    <para>It is also possible to embed the UI description in the source
-    code as a string and use gtk_builder_add_from_string() to load it.
-    But keeping the UI description in a separate file has several
-    advantages: It is then possible to make minor adjustments to the UI
-    without recompiling your program, and, more importantly, graphical
-    UI editors such as <ulink url="http://glade.gnome.org">glade</ulink>
-    can load the file and allow you to create and modify your UI by
-    point-and-click.</para>
-  </section>
-
-  <section>
-    <title>Building applications</title>
-
-    <para>An application consists of a number of files:
-    <variablelist>
-      <varlistentry>
-        <term>The binary</term>
-        <listitem>This gets installed in <filename>/usr/bin</filename>.</listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>A desktop file</term>
-        <listitem>The desktop file provides important information about the application to the desktop shell, such as its name, icon, D-Bus name, commandline to launch it, etc. It is installed in <filename>/usr/share/applications</filename>.</listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>An icon</term>
-        <listitem>The icon gets installed in <filename>/usr/share/icons/hicolor/48x48/apps</filename>, where it will be found regardless of the current theme.</listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>A settings schema</term>
-        <listitem>If the application uses GSettings, it will install its schema
-          in <filename>/usr/share/glib-2.0/schemas</filename>, so that tools
-          like dconf-editor can find it.</listitem>
-      </varlistentry>
-      <varlistentry>
-        <term>Other resources</term>
-        <listitem>Other files, such as GtkBuilder ui files, are best loaded from
-          resources stored in the application binary itself. This eliminates the
-          need for most of the files that would traditionally be installed in
-          an application-specific location in <filename>/usr/share</filename>.</listitem>
-      </varlistentry>
-    </variablelist>
-    </para>
-
-    <para>GTK+ includes application support that is built on top of
-    #GApplication. In this tutorial we'll build a simple application by
-    starting from scratch, adding more and more pieces over time. Along
-    the way, we'll learn about #GtkApplication, templates, resources,
-    application menus, settings, #GtkHeaderBar, #GtkStack, #GtkSearchBar,
-    #GtkListBox, and more.</para>
-
-    <para>The full, buildable sources for these examples can be found
-    in the examples/ directory of the GTK+ source distribution, or
-    <ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples">online</ulink> in the GTK+ git repository.
-    You can build each example separately by using make with the <filename>Makefile.example</filename>
-    file. For more information, see the <filename>README</filename> included in the
-    examples directory.</para>
-
-    <section>
-      <title>A trivial application</title>
-
-      <para>When using #GtkApplication, the main() function can be very
-      simple. We just call g_application_run() and give it an instance
-      of our application class.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application1/main.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>All the application logic is in the application class, which
-      is a subclass of #GtkApplication. Our example does not yet have any
-      interesting functionality. All it does is open a window when it is
-      activated without arguments, and open the files it is given, if it
-      is started with arguments.</para>
-
-      <para>To handle these two cases, we override the activate() vfunc,
-      which gets called when the application is launched without commandline
-      arguments, and the open() vfunc, which gets called when the application
-      is launched with commandline arguments.</para>
-
-      <para>To learn more about GApplication entry points, consult the
-      GIO <ulink url="https://developer.gnome.org/gio/2.36/GApplication.html#GApplication.description">documentation</ulink>.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application1/exampleapp.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Another important class that is part of the application support
-      in GTK+ is #GtkApplicationWindow. It is typically subclassed as well.
-      Our subclass does not do anything yet, so we will just get an empty
-      window.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application1/exampleappwin.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>As part of the initial setup of our application, we also
-      create an icon and a desktop file.</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="exampleapp.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application1/org.gtk.exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced
-      with the actual path to the binary before this desktop file can be used.</para>
-
-      <para>Here is what we've achieved so far:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app1.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-
-      <para>This does not look very impressive yet, but our application
-      is already presenting itself on the session bus, it has single-instance
-      semantics, and it accepts files as commandline arguments.</para>
-    </section>
-
-    <section>
-      <title>Populating the window</title>
-
-      <para>In this step, we use a #GtkBuilder template to associate a
-      #GtkBuilder ui file with our application window class.</para>
-      <para>Our simple ui file puts a #GtkHeaderBar on top of a #GtkStack
-      widget. The header bar contains a #GtkStackSwitcher, which is a
-      standalone widget to show a row of 'tabs' for the pages of a #GtkStack.
-      </para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application2/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>To make use of this file in our application, we revisit
-      our #GtkApplicationWindow subclass, and call
-      gtk_widget_class_set_template_from_resource() from the class init
-      function to set the ui file as template for this class. We also
-      add a call to gtk_widget_init_template() in the instance init
-      function to instantiate the template for each instance of our
-      class.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
- ...
-
-static void
-example_app_window_init (ExampleAppWindow *win)
-{
-  gtk_widget_init_template (GTK_WIDGET (win));
-}
-
-static void
-example_app_window_class_init (ExampleAppWindowClass *class)
-{
-  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
-                                               "/org/gtk/exampleapp/window.ui");
-}
-
- ...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>You may have noticed that we used the <literal>_from_resource(<!-- -->)</literal> variant
-      of the function that sets a template. Now we need to use <ulink url="https://developer.gnome.org/gio/stable/GResource.html">GLib's resource functionality</ulink>
-      to include the ui file in the binary. This is commonly done by listing
-      all resources in a .gresource.xml file, such as this:
-      </para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application2/exampleapp.gresource.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>This file has to be converted into a C source file that will be
-      compiled and linked into the application together with the other source
-      files. To do so, we use the glib-compile-resources utility:</para>
-
-      <screen>
-      glib-compile-resources exampleapp.gresource.xml --target=resources.c --generate-source
-      </screen>
-
-      <para>Our application now looks like this:</para>
-
-      <informalfigure>
-       <mediaobject>
-        <imageobject>
-          <imagedata fileref="getting-started-app2.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-      </informalfigure>
-    </section>
-
-    <section>
-      <title>Opening files</title>
-
-      <para>In this step, we make our application show the content of
-      all the files that it is given on the commandline.</para>
-
-      <para>To this end, we add a member to the struct in application
-      window subclass and keep a reference to the #GtkStack there.
-      The first member of the struct should be the parent type from
-      which the class is derived. Here, ExampleAppWindow is derived
-      from GtkApplicationWindow.
-      The gtk_widget_class_bind_template_child() function
-      arranges things so that after instantiating the template, the
-      @stack member of the struct will point to the widget of
-      the same name from the template.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-struct _ExampleAppWindow
-{
-  GtkApplicationWindow parent;
-
-  GtkWidget *stack;
-};
-
-G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
-
-...
-
-static void
-example_app_window_class_init (ExampleAppWindowClass *class)
-{
-  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
-                                               "/org/gtk/exampleapp/window.ui");
-  gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>Now we revisit the example_app_window_open() function that
-      is called for each commandline argument, and construct a GtkTextView
-      that we then add as a page to the stack:</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-void
-example_app_window_open (ExampleAppWindow *win,
-                         GFile            *file)
-{
-  gchar *basename;
-  GtkWidget *scrolled, *view;
-  gchar *contents;
-  gsize length;
-
-  basename = g_file_get_basename (file);
-
-  scrolled = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_set_hexpand (scrolled, TRUE);
-  gtk_widget_set_vexpand (scrolled, TRUE);
-  view = gtk_text_view_new ();
-  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
-  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
-  gtk_container_add (GTK_CONTAINER (scrolled), view);
-  gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
-
-  if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
-    {
-      GtkTextBuffer *buffer;
-
-      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-      gtk_text_buffer_set_text (buffer, contents, length);
-      g_free (contents);
-    }
-
-  g_free (basename);
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>Note that we did not have to touch the stack switcher
-      at all. It gets all its information from the stack that it
-      belongs to. Here, we are passing the label to show for each
-      file as the last argument to the gtk_stack_add_titled()
-      function.</para>
-
-      <para>Our application is beginning to take shape:</para>
-
-      <informalfigure>
-       <mediaobject>
-        <imageobject>
-          <imagedata fileref="getting-started-app3.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-      </informalfigure>
-    </section>
-
-    <section>
-      <title>An application menu</title>
-
-      <para>An application menu is shown by GNOME shell at the top of the
-      screen. It is meant to collect infrequently used actions that affect
-      the whole application.</para>
-
-      <para>Just like the window template, we specify our application menu
-      in a ui file, and add it as a resource to our binary.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application4/app-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>To associate the app menu with the application, we have to call
-      gtk_application_set_app_menu(). Since app menus work by activating
-      #GActions, we also have to add a suitable set of actions to our
-      application.</para>
-
-      <para>Both of these tasks are best done in the startup() vfunc,
-      which is guaranteed to be called once for each primary application
-      instance:</para>
-      <informalexample>
-        <programlisting>
-...
-
-static void
-preferences_activated (GSimpleAction *action,
-                       GVariant      *parameter,
-                       gpointer       app)
-{
-}
-
-static void
-quit_activated (GSimpleAction *action,
-                GVariant      *parameter,
-                gpointer       app)
-{
-  g_application_quit (G_APPLICATION (app));
-}
-
-static GActionEntry app_entries[] =
-{
-  { "preferences", preferences_activated, NULL, NULL, NULL },
-  { "quit", quit_activated, NULL, NULL, NULL }
-};
-
-static void
-example_app_startup (GApplication *app)
-{
-  GtkBuilder *builder;
-  GMenuModel *app_menu;
-  const gchar *quit_accels[2] = { "&lt;Ctrl&gt;Q", NULL };
-
-  G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
-
-  g_action_map_add_action_entries (G_ACTION_MAP (app),
-                                   app_entries, G_N_ELEMENTS (app_entries),
-                                   app);
-  gtk_application_set_accels_for_action (GTK_APPLICATION (app),
-                                         "app.quit",
-                                         quit_accels);
-
-  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
-  app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
-  gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
-  g_object_unref (builder);
-}
-
-static void
-example_app_class_init (ExampleAppClass *class)
-{
-  G_APPLICATION_CLASS (class)->startup = example_app_startup;
-  ...
-}
-
-...
-        </programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>Our preferences menu item does not do anything yet,
-      but the Quit menu item is fully functional. Note that it
-      can also be activated by the usual Ctrl-Q shortcut. The
-      shortcut was added with gtk_application_set_accels_for_action().
-      </para>
-
-      <para>The application menu looks like this:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app4.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-    </section>
-
-    <section>
-      <title>A preference dialog</title>
-
-      <para>A typical application will have a some preferences that
-      should be remembered from one run to the next. Even for our
-      simple example application, we may want to change the font
-      that is used for the content.</para>
-
-      <para>We are going to use GSettings to store our preferences.
-      GSettings requires a schema that describes our settings:</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application5/org.gtk.exampleapp.gschema.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Before we can make use of this schema in our application,
-      we need to compile it into the binary form that GSettings
-      expects. GIO provides <ulink url="https://developer.gnome.org/gio/2.36/ch31s06.html">macros</ulink>
-      to do this in autotools-based projects.</para>
-
-      <para>Next, we need to connect our settings to the widgets
-      that they are supposed to control. One convenient way to do
-      this is to use GSettings bind functionality to bind settings
-      keys to object properties, as we do here for the transition
-      setting.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-static void
-example_app_window_init (ExampleAppWindow *win)
-{
-  gtk_widget_init_template (GTK_WIDGET (win));
-  win->settings = g_settings_new ("org.gtk.exampleapp");
-
-  g_settings_bind (win->settings, "transition",
-                   win->stack, "transition-type",
-                   G_SETTINGS_BIND_DEFAULT);
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>The code to connect the font setting is a little more involved,
-      since there is no simple object property that it corresponds to, so
-      we are not going to go into that here.</para>
-
-      <para>At this point, the application will already react if you
-      change one of the settings, e.g. using the gsettings commandline
-      tool. Of course, we expect the application to provide a preference
-      dialog for these. So lets do that now. Our preference dialog will
-      be a subclass of GtkDialog, and we'll use the same techniques that
-      we've already seen: templates, private structs, settings
-      bindings.</para>
-
-      <para>Lets start with the template.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application6/prefs.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Next comes the dialog subclass.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application6/exampleappprefs.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Now we revisit the <literal>preferences_activated(<!-- -->)</literal> function in our
-      application class, and make it open a new preference dialog.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-static void
-preferences_activated (GSimpleAction *action,
-                       GVariant      *parameter,
-                       gpointer       app)
-{
-  ExampleAppPrefs *prefs;
-  GtkWindow *win;
-
-  win = gtk_application_get_active_window (GTK_APPLICATION (app));
-  prefs = example_app_prefs_new (EXAMPLE_APP_WINDOW (win));
-  gtk_window_present (GTK_WINDOW (prefs));
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>After all this work, our application can now show
-      a preference dialog like this:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app6.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-    </section>
-
-    <section>
-      <title>Adding a search bar</title>
-
-      <para>We continue to flesh out the functionality of our application.
-      For now, we add search. GTK+ supports this with #GtkSearchEntry and
-      #GtkSearchBar. The search bar is a widget that can slide in from the
-      top to present a search entry.</para>
-
-      <para>We add a toggle button to the header bar, which can be used
-      to slide out the search bar below the header bar.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application7/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>Implementing the search needs quite a few code changes that
-      we are not going to completely go over here. The central piece of
-      the search implementation is a signal handler that listens for
-      text changes in the search entry.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-static void
-search_text_changed (GtkEntry         *entry,
-                     ExampleAppWindow *win)
-{
-  const gchar *text;
-  GtkWidget *tab;
-  GtkWidget *view;
-  GtkTextBuffer *buffer;
-  GtkTextIter start, match_start, match_end;
-
-  text = gtk_entry_get_text (entry);
-
-  if (text[0] == '\0')
-    return;
-
-  tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
-  view = gtk_bin_get_child (GTK_BIN (tab));
-  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
-  /* Very simple-minded search implementation */
-  gtk_text_buffer_get_start_iter (buffer, &start);
-  if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
-                                    &match_start, &match_end, NULL))
-    {
-      gtk_text_buffer_select_range (buffer, &match_start, &match_end);
-      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
-                                    0.0, FALSE, 0.0, 0.0);
-    }
-}
-
-static void
-example_app_window_init (ExampleAppWindow *win)
-{
-
-...
-
-  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
-
-...
-
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>With the search bar, our application now looks like this:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app7.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-    </section>
-
-    <section>
-      <title>Adding a side bar</title>
-
-      <para>As another piece of functionality, we are adding a sidebar,
-      which demonstrates #GtkMenuButton, #GtkRevealer and #GtkListBox.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application8/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>The code to populate the sidebar with buttons for the words
-      found in each file is a little too involved to go into here. But we'll
-      look at the code to add the gears menu.</para>
-
-      <para>As expected by now, the gears menu is specified in a GtkBuilder
-      ui file.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application8/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>To connect the menuitem to the show-words setting, we use
-      a #GAction corresponding to the given #GSettings key.</para>
-
-      <informalexample>
-        <programlisting><![CDATA[
-...
-
-static void
-example_app_window_init (ExampleAppWindow *win)
-{
-
-...
-
-  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
-  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
-  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->gears), menu);
-  g_object_unref (builder);
-
-  action = g_settings_create_action (priv->settings, "show-words");
-  g_action_map_add_action (G_ACTION_MAP (win), action);
-  g_object_unref (action);
-}
-
-...
-        ]]></programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>What our application looks like now:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app8.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-    </section>
-    <section>
-      <title>Properties</title>
-
-      <para>Widgets and other objects have many useful properties.</para>
-
-      <para>Here we show some ways to use them in new and flexible ways,
-      by wrapping them in actions with #GPropertyAction or by binding them
-      with #GBinding.</para>
-
-      <para>To set this up, we add two labels to the header bar in our
-      window template, named @lines_label and @lines, and bind them to
-      struct members in the private struct, as we've seen a couple of times
-      by now.</para>
-
-      <para>We add a new "Lines" menu item to the gears menu, which
-      triggers the show-lines action:</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application9/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>To make this menu item do something, we create a property
-      action for the visible property of the @lines label, and add it to the
-      actions of the window. The effect of this is that the visibility
-      of the label gets toggled every time the action is activated.</para>
-
-      <para>Since we want both labels to appear and disappear together,
-      we bind the visible property of the @lines_label widget to the
-      same property of the @lines widget.</para>
-
-      <informalexample>
-        <programlisting>
-...
-
-static void
-example_app_window_init (ExampleAppWindow *win)
-{
-  ...
-
-  action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
-  g_action_map_add_action (G_ACTION_MAP (win), action);
-  g_object_unref (action);
-
-  g_object_bind_property (win->lines, "visible",
-                          win->lines_label, "visible",
-                          G_BINDING_DEFAULT);
-}
-
-...
-        </programlisting>
-        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>)</para>
-      </informalexample>
-
-      <para>We also need a function that counts the lines of the currently
-      active tab, and updates the @lines label. See the
-      <ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>
-      if you are interested in the details.</para>
-
-      <para>This brings our example application to this appearance:</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app9.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-    </section>
-    <section>
-      <title>Header bar</title>
-
-      <para>Our application already uses a GtkHeaderBar, but so far it
-      still gets a 'normal' window titlebar on top of that. This is a
-      bit redundant, and we will now tell GTK+ to use the header bar
-      as replacement for the titlebar. To do so, we move it around to
-      be a direct child of the window, and set its type to be titlebar.</para>
-
-      <informalexample>
-        <programlisting><xi:include href="../../../../examples/application10/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-      </informalexample>
-
-      <para>A small extra bonus of using a header bar is that we get
-      a fallback application menu for free. Here is how the
-      application now looks, if this fallback is used.</para>
-
-      <informalfigure>
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="getting-started-app10.png" format="PNG"/>
-          </imageobject>
-        </mediaobject>
-      </informalfigure>
-
-      <para>If we set up the window icon for our window, the menu button
-      will use that instead of the generic placeholder icon you see
-      here.</para>
-    </section>
-  </section>
-
-  <section>
-    <title>Custom Drawing</title>
-
-    <para>Many widgets, like buttons, do all their drawing themselves. You
-    just tell them the label you want to see, and they figure out what font
-    to use, draw the button outline and focus rectangle, etc. Sometimes, it
-    is necessary to do some custom drawing. In that case, a #GtkDrawingArea
-    might be the right widget to use. It offers a canvas on which you can
-    draw by connecting to the #GtkWidget::draw signal.
-    </para>
-
-    <para>The contents of a widget often need to be partially or fully redrawn,
-    e.g. when another window is moved and uncovers part of the widget, or
-    when the window containing it is resized. It is also possible to explicitly
-    cause part or all of the widget to be redrawn, by calling
-    gtk_widget_queue_draw() or its variants. GTK+ takes care of most of the
-    details by providing a ready-to-use cairo context to the ::draw signal
-    handler.</para>
-
-    <para>The following example shows a ::draw signal handler. It is a bit
-    more complicated than the previous examples, since it also demonstrates
-    input event handling by means of ::button-press and ::motion-notify
-    handlers.</para>
-
-    <informalfigure>
-      <mediaobject>
-        <imageobject>
-          <imagedata fileref="drawing.png" format="PNG"/>
-        </imageobject>
-      </mediaobject>
-    </informalfigure>
-
-    <example id="gtk-getting-started-drawing">
-      <title>Drawing in response to input</title>
-      <para>Create a new file with the following content named example-4.c.</para>
-      <programlisting><xi:include href="../../../../examples/drawing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
-    </example>
-    <para>
-      You can compile the program above with GCC using:
-      <literallayout>
-        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-4 example-4.c `pkg-config --libs gtk+-4.0`</literal>
-      </literallayout>
-    </para>
-  </section>
-
-</chapter>
diff --git a/docs/reference/gtk/getting_started.xml.in b/docs/reference/gtk/getting_started.xml.in
new file mode 100644 (file)
index 0000000..0a6f99c
--- /dev/null
@@ -0,0 +1,1081 @@
+<?xml version="1.0"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+]>
+<chapter id="gtk-getting-started" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <title>Getting Started with GTK+</title>
+
+  <para>GTK+ is a <ulink url="http://en.wikipedia.org/wiki/Widget_toolkit">
+  widget toolkit</ulink>. Each user interface created by 
+  GTK+ consists of widgets. This is implemented in C using 
+  <link linkend="gobject">GObject</link>, an object-oriented framework for C.
+  Widgets are organized in a hierachy. The window widget is the main container.
+  The user interface is then built by adding buttons, drop-down menus, input 
+  fields, and other widgets to the window.
+  If you are creating complex user interfaces it is recommended to
+  use #GtkBuilder and its GTK-specific markup description language, instead of
+  assembling the interface manually. You can also use a visual user interface
+  editor, like <ulink url="https://glade.gnome.org/">Glade</ulink>.</para>
+  
+  <para>GTK+ is event-driven. The toolkit listens for events such as
+  a click on a button, and passes the event to your application.</para>
+
+  <para>This chapter contains some tutorial information to get you
+  started with GTK+ programming. It assumes that you have GTK+, its
+  dependencies and a C compiler installed and ready to use. If you
+  need to build GTK+ itself first, refer to the
+  <link linkend="gtk-compiling">Compiling the GTK+ libraries</link>
+  section in this reference.</para>
+
+  <section>
+    <title>Basics</title>
+
+    <para>To begin our introduction to GTK, we'll start with a simple
+    signal-based Gtk application. This program will create an empty 200 × 200 pixel
+    window.</para>
+
+    <informalfigure>
+      <mediaobject>
+        <imageobject>
+          <imagedata fileref="window-default.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+    </informalfigure>
+
+    <informalexample>
+      <para>Create a new file with the following content named <filename>example-0.c.</filename></para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/window-default.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+    </informalexample>
+
+    <para>
+      You can compile the program above with GCC using:
+      <literallayout>
+        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-0 example-0.c `pkg-config --libs gtk+-4.0`</literal>
+      </literallayout>
+    </para>
+
+    <note><para>For more information on how to compile a GTK+ application, please
+    refer to the <link linkend="gtk-compiling">Compiling GTK+ Applications</link>
+    section in this reference.</para></note>
+
+    <para>All GTK+ applications will, of course, include
+    <filename>gtk/gtk.h</filename>, which declares functions, types and
+    macros required by GTK+ applications.</para>
+
+    <warning><para>Even if GTK+ installs multiple header files, only the
+    top-level <filename>gtk/gtk.h</filename> header can be directly included
+    by third party code. The compiler will abort with an error if any other
+    header is directly included.</para></warning>
+
+    <para>In a GTK+ application, the purpose of the main() function is to
+    create a #GtkApplication object and run it. In this example a
+    #GtkApplication pointer named <varname>app</varname> is called and then
+    initialized using gtk_application_new().</para>
+
+    <para>When creating a #GtkApplication
+    you need to pick an application identifier (a name)
+    and input to gtk_application_new() as parameter.
+    For this example <varname>org.gtk.example</varname> is used
+    but for choosing an identifier for your application see
+    <ulink url="https://wiki.gnome.org/HowDoI/ChooseApplicationID">this guide</ulink>.
+    Lastly gtk_application_new() takes a GApplicationFlags as input for your 
+    application, if your application would have special needs.
+    </para>
+
+    <para>Next the
+    <ulink url="https://wiki.gnome.org/HowDoI/GtkApplication">activate signal</ulink>
+    is connected to the activate() function above the main() functions.
+    The <varname>activate</varname> signal will be sent
+    when your application is launched with
+    g_application_run() on the line below.
+    The gtk_application_run() also takes as arguments the pointers to the command line arguments
+    counter and string array; this allows GTK+ to parse specific command line
+    arguments that control the behavior of GTK+ itself. The parsed arguments
+    will be removed from the array, leaving the unrecognized ones for your
+    application to parse.
+    </para>
+
+    <para>Within g_application_run the activate() signal is sent and
+    we then proceed into the <function>activate</function>() function of the
+    application. Inside the activate() function we want to construct
+    our GTK window, so that a window is shown when the application
+    is launched. The call to gtk_application_window_new() will
+    create a new #GtkWindow and store it inside the
+    <varname>window</varname> pointer. The window will have a frame,
+    a title bar, and window controls depending on the platform.</para>
+
+    <para>A window title is set using gtk_window_set_title(). This function
+    takes a GtkWindow* pointer and a string as input. As our
+    <varname>window</varname> pointer is a GtkWidget pointer, we need to cast it
+    to GtkWindow*.
+    But instead of casting <varname>window</varname> via
+    <varname>(GtkWindow*)</varname>, 
+    <varname>window</varname> can be cast using the macro
+    <varname>GTK_WINDOW()</varname>.
+    <varname>GTK_WINDOW()</varname> will check if the 
+    pointer is an instance of the GtkWindow class, before casting, and emit a
+    warning if the check fails. More information about this convention 
+    can be found 
+    <ulink url="https://developer.gnome.org/gobject/stable/gtype-conventions.html">
+    here</ulink>.</para>
+
+    <para>Finally the window size is set using gtk_window_set_default_size and
+    the window is then shown by GTK via gtk_widget_show().</para>
+
+    <para>When you exit the window, by for example pressing the X,
+    the g_application_run() in the main loop returns with a number
+    which is saved inside an integer named "status". Afterwards, the
+    #GtkApplication object is freed from memory with g_object_unref().
+    Finally the status integer is returned and the GTK application exits.</para>
+
+    <para>While the program is running, GTK+ is receiving
+    <firstterm>events</firstterm>. These are typically input events caused by
+    the user interacting with your program, but also things like messages from
+    the window manager or other applications. GTK+ processes these and as a
+    result, <firstterm>signals</firstterm> may be emitted on your widgets.
+    Connecting handlers for these signals is how you normally make your
+    program do something in response to user input.</para>
+
+    <para>The following example is slightly more complex, and tries to
+    showcase some of the capabilities of GTK+.</para>
+
+    <para>In the long tradition of programming languages and libraries,
+    it is called <emphasis>Hello, World</emphasis>.</para>
+
+    <informalfigure>
+      <mediaobject>
+        <imageobject>
+          <imagedata fileref="hello-world.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+    </informalfigure>
+
+    <example id="gtk-getting-started-hello-world">
+      <title>Hello World in GTK+</title>
+      <para>Create a new file with the following content named example-1.c.</para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/hello-world.c" parse="text">
+          <xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+    </example>
+
+    <para>
+      You can compile the program above with GCC using:
+      <literallayout>
+        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-1 example-1.c `pkg-config --libs gtk+-4.0`</literal>
+      </literallayout>
+    </para>
+  </section>
+
+  <para>As seen above, example-1.c builds further upon example-0.c by adding a
+  button to our window, with the label "Hello World". Two new GtkWidget pointers
+  are declared to accomplish this, <varname>button</varname> and
+  <varname>button_box</varname>. The button_box variable is created to store a
+  #GtkButtonBox which is GTK+'s way of controlling the size and layout of buttons.
+  The #GtkButtonBox is created and assigned to gtk_button_box_new() which takes a
+  #GtkOrientation enum as parameter. The buttons which this box will contain can
+  either be stored horizontally or vertically but this does not matter in this
+  particular case as we are dealing with only one button. After initializing
+  button_box with horizontal orientation, the code adds the button_box widget to the
+  window widget using gtk_container_add().</para>
+
+  <para>Next the <varname>button</varname> variable is initialized in similar manner.
+  gtk_button_new_with_label() is called which returns a GtkButton to be stored inside
+  <varname>button</varname>. Afterwards <varname>button</varname> is added to
+  our <varname>button_box</varname>.
+  Using g_signal_connect the button is connected to a function in our app called
+  print_hello(), so that when the button is clicked, GTK will call this function.
+  As the print_hello() function does not use any data as input, NULL is passed
+  to it. print_hello() calls g_print() with the string "Hello World"
+  which will print Hello World in a terminal if the GTK application was started
+  from one.</para>
+
+  <para>After connecting print_hello(), another signal is connected to the "clicked" state
+  of the button using g_signal_connect_swapped(). This functions is similar to
+  a g_signal_connect() with the difference lying in how the callback function is
+  treated. g_signal_connect_swapped() allow you to specify what the callback
+  function should take as parameter by letting you pass it as data. In this case
+  the function being called back is gtk_widget_destroy() and the <varname>window</varname>
+  pointer is passed to it. This has the effect that when the button is clicked,
+  the whole GTK window is destroyed. In contrast if a normal g_signal_connect() were used
+  to connect the "clicked" signal with gtk_widget_destroy(), then the <varname>button</varname>
+  itself would have been destroyed, not the window.
+  More information about creating buttons can be found
+  <ulink url="https://wiki.gnome.org/HowDoI/Buttons">here</ulink>.
+  </para>
+
+  <para>The rest of the code in example-1.c is identical to example-0.c. Next
+  section will elaborate further on how to add several GtkWidgets to your GTK
+  application.</para>
+
+  <section>
+    <title>Packing</title>
+
+    <para>When creating an application, you'll want to put more than one widget
+    inside a window.
+    When you want to put more than one widget into a window,
+    it becomes important to control how each widget is positioned and sized.
+    This is where packing comes in.</para>
+
+    <para>GTK+ comes with a large variety of <firstterm>layout containers</firstterm>
+    whose purpose it is to control the layout of the child widgets that are
+    added to them. See <xref linkend="LayoutContainers"/> for an overview.</para>
+
+    <para>The following example shows how the GtkGrid container lets you
+    arrange several buttons:</para>
+
+    <informalfigure>
+      <mediaobject>
+        <imageobject>
+          <imagedata fileref="grid-packing.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+    </informalfigure>
+
+    <example id="gtk-getting-started-grid-packing">
+      <title>Packing buttons</title>
+      <para>Create a new file with the following content named example-2.c.</para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/grid-packing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+    </example>
+    <para>
+      You can compile the program above with GCC using:
+      <literallayout>
+        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-2 example-2.c `pkg-config --libs gtk+-4.0`</literal>
+      </literallayout>
+    </para>
+  </section>
+
+  <section>
+    <title>Building user interfaces</title>
+
+    <para>When construcing a more complicated user interface, with dozens
+    or hundreds of widgets, doing all the setup work in C code is
+    cumbersome, and making changes becomes next to impossible.</para>
+
+    <para>Thankfully, GTK+ supports the separation of user interface
+    layout from your business logic, by using UI descriptions in an
+    XML format that can be parsed by the #GtkBuilder class.</para>
+
+    <example>
+      <title>Packing buttons with GtkBuilder</title>
+      <para>Create a new file with the following content named example-3.c.</para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/builder.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      <para>Create a new file with the following content named builder.ui.</para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/builder.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+    </example>
+    <para>
+      You can compile the program above with GCC using:
+      <literallayout>
+        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-3 example-3.c `pkg-config --libs gtk+-4.0`</literal>
+      </literallayout>
+    </para>
+
+    <para>Note that GtkBuilder can also be used to construct objects
+    that are not widgets, such as tree models, adjustments, etc.
+    That is the reason the method we use here is called
+    gtk_builder_get_object() and returns a GObject* instead of a
+    GtkWidget*.</para>
+
+    <para>Normally, you would pass a full path to
+    gtk_builder_add_from_file() to make the execution of your program
+    independent of the current directory. A common location to install
+    UI descriptions and similar data is
+    <filename>/usr/share/<replaceable>appname</replaceable></filename>.
+    </para>
+
+    <para>It is also possible to embed the UI description in the source
+    code as a string and use gtk_builder_add_from_string() to load it.
+    But keeping the UI description in a separate file has several
+    advantages: It is then possible to make minor adjustments to the UI
+    without recompiling your program, and, more importantly, graphical
+    UI editors such as <ulink url="http://glade.gnome.org">glade</ulink>
+    can load the file and allow you to create and modify your UI by
+    point-and-click.</para>
+  </section>
+
+  <section>
+    <title>Building applications</title>
+
+    <para>An application consists of a number of files:
+    <variablelist>
+      <varlistentry>
+        <term>The binary</term>
+        <listitem>This gets installed in <filename>/usr/bin</filename>.</listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>A desktop file</term>
+        <listitem>The desktop file provides important information about the application to the desktop shell, such as its name, icon, D-Bus name, commandline to launch it, etc. It is installed in <filename>/usr/share/applications</filename>.</listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>An icon</term>
+        <listitem>The icon gets installed in <filename>/usr/share/icons/hicolor/48x48/apps</filename>, where it will be found regardless of the current theme.</listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>A settings schema</term>
+        <listitem>If the application uses GSettings, it will install its schema
+          in <filename>/usr/share/glib-2.0/schemas</filename>, so that tools
+          like dconf-editor can find it.</listitem>
+      </varlistentry>
+      <varlistentry>
+        <term>Other resources</term>
+        <listitem>Other files, such as GtkBuilder ui files, are best loaded from
+          resources stored in the application binary itself. This eliminates the
+          need for most of the files that would traditionally be installed in
+          an application-specific location in <filename>/usr/share</filename>.</listitem>
+      </varlistentry>
+    </variablelist>
+    </para>
+
+    <para>GTK+ includes application support that is built on top of
+    #GApplication. In this tutorial we'll build a simple application by
+    starting from scratch, adding more and more pieces over time. Along
+    the way, we'll learn about #GtkApplication, templates, resources,
+    application menus, settings, #GtkHeaderBar, #GtkStack, #GtkSearchBar,
+    #GtkListBox, and more.</para>
+
+    <para>The full, buildable sources for these examples can be found
+    in the examples/ directory of the GTK+ source distribution, or
+    <ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples">online</ulink> in the GTK+ git repository.
+    You can build each example separately by using make with the <filename>Makefile.example</filename>
+    file. For more information, see the <filename>README</filename> included in the
+    examples directory.</para>
+
+    <section>
+      <title>A trivial application</title>
+
+      <para>When using #GtkApplication, the main() function can be very
+      simple. We just call g_application_run() and give it an instance
+      of our application class.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application1/main.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>All the application logic is in the application class, which
+      is a subclass of #GtkApplication. Our example does not yet have any
+      interesting functionality. All it does is open a window when it is
+      activated without arguments, and open the files it is given, if it
+      is started with arguments.</para>
+
+      <para>To handle these two cases, we override the activate() vfunc,
+      which gets called when the application is launched without commandline
+      arguments, and the open() vfunc, which gets called when the application
+      is launched with commandline arguments.</para>
+
+      <para>To learn more about GApplication entry points, consult the
+      GIO <ulink url="https://developer.gnome.org/gio/2.36/GApplication.html#GApplication.description">documentation</ulink>.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application1/exampleapp.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Another important class that is part of the application support
+      in GTK+ is #GtkApplicationWindow. It is typically subclassed as well.
+      Our subclass does not do anything yet, so we will just get an empty
+      window.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application1/exampleappwin.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>As part of the initial setup of our application, we also
+      create an icon and a desktop file.</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="exampleapp.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application1/org.gtk.exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced
+      with the actual path to the binary before this desktop file can be used.</para>
+
+      <para>Here is what we've achieved so far:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app1.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+
+      <para>This does not look very impressive yet, but our application
+      is already presenting itself on the session bus, it has single-instance
+      semantics, and it accepts files as commandline arguments.</para>
+    </section>
+
+    <section>
+      <title>Populating the window</title>
+
+      <para>In this step, we use a #GtkBuilder template to associate a
+      #GtkBuilder ui file with our application window class.</para>
+      <para>Our simple ui file puts a #GtkHeaderBar on top of a #GtkStack
+      widget. The header bar contains a #GtkStackSwitcher, which is a
+      standalone widget to show a row of 'tabs' for the pages of a #GtkStack.
+      </para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application2/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>To make use of this file in our application, we revisit
+      our #GtkApplicationWindow subclass, and call
+      gtk_widget_class_set_template_from_resource() from the class init
+      function to set the ui file as template for this class. We also
+      add a call to gtk_widget_init_template() in the instance init
+      function to instantiate the template for each instance of our
+      class.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+ ...
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+  gtk_widget_init_template (GTK_WIDGET (win));
+}
+
+static void
+example_app_window_class_init (ExampleAppWindowClass *class)
+{
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gtk/exampleapp/window.ui");
+}
+
+ ...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>You may have noticed that we used the <literal>_from_resource(<!-- -->)</literal> variant
+      of the function that sets a template. Now we need to use <ulink url="https://developer.gnome.org/gio/stable/GResource.html">GLib's resource functionality</ulink>
+      to include the ui file in the binary. This is commonly done by listing
+      all resources in a .gresource.xml file, such as this:
+      </para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application2/exampleapp.gresource.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>This file has to be converted into a C source file that will be
+      compiled and linked into the application together with the other source
+      files. To do so, we use the glib-compile-resources utility:</para>
+
+      <screen>
+      glib-compile-resources exampleapp.gresource.xml --target=resources.c --generate-source
+      </screen>
+
+      <para>Our application now looks like this:</para>
+
+      <informalfigure>
+       <mediaobject>
+        <imageobject>
+          <imagedata fileref="getting-started-app2.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+      </informalfigure>
+    </section>
+
+    <section>
+      <title>Opening files</title>
+
+      <para>In this step, we make our application show the content of
+      all the files that it is given on the commandline.</para>
+
+      <para>To this end, we add a member to the struct in application
+      window subclass and keep a reference to the #GtkStack there.
+      The first member of the struct should be the parent type from
+      which the class is derived. Here, ExampleAppWindow is derived
+      from GtkApplicationWindow.
+      The gtk_widget_class_bind_template_child() function
+      arranges things so that after instantiating the template, the
+      @stack member of the struct will point to the widget of
+      the same name from the template.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+struct _ExampleAppWindow
+{
+  GtkApplicationWindow parent;
+
+  GtkWidget *stack;
+};
+
+G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW)
+
+...
+
+static void
+example_app_window_class_init (ExampleAppWindowClass *class)
+{
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gtk/exampleapp/window.ui");
+  gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>Now we revisit the example_app_window_open() function that
+      is called for each commandline argument, and construct a GtkTextView
+      that we then add as a page to the stack:</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+void
+example_app_window_open (ExampleAppWindow *win,
+                         GFile            *file)
+{
+  gchar *basename;
+  GtkWidget *scrolled, *view;
+  gchar *contents;
+  gsize length;
+
+  basename = g_file_get_basename (file);
+
+  scrolled = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_set_hexpand (scrolled, TRUE);
+  gtk_widget_set_vexpand (scrolled, TRUE);
+  view = gtk_text_view_new ();
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
+  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
+  gtk_container_add (GTK_CONTAINER (scrolled), view);
+  gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename);
+
+  if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
+    {
+      GtkTextBuffer *buffer;
+
+      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+      gtk_text_buffer_set_text (buffer, contents, length);
+      g_free (contents);
+    }
+
+  g_free (basename);
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>Note that we did not have to touch the stack switcher
+      at all. It gets all its information from the stack that it
+      belongs to. Here, we are passing the label to show for each
+      file as the last argument to the gtk_stack_add_titled()
+      function.</para>
+
+      <para>Our application is beginning to take shape:</para>
+
+      <informalfigure>
+       <mediaobject>
+        <imageobject>
+          <imagedata fileref="getting-started-app3.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+      </informalfigure>
+    </section>
+
+    <section>
+      <title>An application menu</title>
+
+      <para>An application menu is shown by GNOME shell at the top of the
+      screen. It is meant to collect infrequently used actions that affect
+      the whole application.</para>
+
+      <para>Just like the window template, we specify our application menu
+      in a ui file, and add it as a resource to our binary.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application4/app-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>To associate the app menu with the application, we have to call
+      gtk_application_set_app_menu(). Since app menus work by activating
+      #GActions, we also have to add a suitable set of actions to our
+      application.</para>
+
+      <para>Both of these tasks are best done in the startup() vfunc,
+      which is guaranteed to be called once for each primary application
+      instance:</para>
+      <informalexample>
+        <programlisting>
+...
+
+static void
+preferences_activated (GSimpleAction *action,
+                       GVariant      *parameter,
+                       gpointer       app)
+{
+}
+
+static void
+quit_activated (GSimpleAction *action,
+                GVariant      *parameter,
+                gpointer       app)
+{
+  g_application_quit (G_APPLICATION (app));
+}
+
+static GActionEntry app_entries[] =
+{
+  { "preferences", preferences_activated, NULL, NULL, NULL },
+  { "quit", quit_activated, NULL, NULL, NULL }
+};
+
+static void
+example_app_startup (GApplication *app)
+{
+  GtkBuilder *builder;
+  GMenuModel *app_menu;
+  const gchar *quit_accels[2] = { "&lt;Ctrl&gt;Q", NULL };
+
+  G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
+
+  g_action_map_add_action_entries (G_ACTION_MAP (app),
+                                   app_entries, G_N_ELEMENTS (app_entries),
+                                   app);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (app),
+                                         "app.quit",
+                                         quit_accels);
+
+  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
+  app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
+  gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
+  g_object_unref (builder);
+}
+
+static void
+example_app_class_init (ExampleAppClass *class)
+{
+  G_APPLICATION_CLASS (class)->startup = example_app_startup;
+  ...
+}
+
+...
+        </programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>Our preferences menu item does not do anything yet,
+      but the Quit menu item is fully functional. Note that it
+      can also be activated by the usual Ctrl-Q shortcut. The
+      shortcut was added with gtk_application_set_accels_for_action().
+      </para>
+
+      <para>The application menu looks like this:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app4.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+    </section>
+
+    <section>
+      <title>A preference dialog</title>
+
+      <para>A typical application will have a some preferences that
+      should be remembered from one run to the next. Even for our
+      simple example application, we may want to change the font
+      that is used for the content.</para>
+
+      <para>We are going to use GSettings to store our preferences.
+      GSettings requires a schema that describes our settings:</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application5/org.gtk.exampleapp.gschema.xml" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Before we can make use of this schema in our application,
+      we need to compile it into the binary form that GSettings
+      expects. GIO provides <ulink url="https://developer.gnome.org/gio/2.36/ch31s06.html">macros</ulink>
+      to do this in autotools-based projects.</para>
+
+      <para>Next, we need to connect our settings to the widgets
+      that they are supposed to control. One convenient way to do
+      this is to use GSettings bind functionality to bind settings
+      keys to object properties, as we do here for the transition
+      setting.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+  gtk_widget_init_template (GTK_WIDGET (win));
+  win->settings = g_settings_new ("org.gtk.exampleapp");
+
+  g_settings_bind (win->settings, "transition",
+                   win->stack, "transition-type",
+                   G_SETTINGS_BIND_DEFAULT);
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>The code to connect the font setting is a little more involved,
+      since there is no simple object property that it corresponds to, so
+      we are not going to go into that here.</para>
+
+      <para>At this point, the application will already react if you
+      change one of the settings, e.g. using the gsettings commandline
+      tool. Of course, we expect the application to provide a preference
+      dialog for these. So lets do that now. Our preference dialog will
+      be a subclass of GtkDialog, and we'll use the same techniques that
+      we've already seen: templates, private structs, settings
+      bindings.</para>
+
+      <para>Lets start with the template.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application6/prefs.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Next comes the dialog subclass.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application6/exampleappprefs.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Now we revisit the <literal>preferences_activated(<!-- -->)</literal> function in our
+      application class, and make it open a new preference dialog.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+static void
+preferences_activated (GSimpleAction *action,
+                       GVariant      *parameter,
+                       gpointer       app)
+{
+  ExampleAppPrefs *prefs;
+  GtkWindow *win;
+
+  win = gtk_application_get_active_window (GTK_APPLICATION (app));
+  prefs = example_app_prefs_new (EXAMPLE_APP_WINDOW (win));
+  gtk_window_present (GTK_WINDOW (prefs));
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>After all this work, our application can now show
+      a preference dialog like this:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app6.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+    </section>
+
+    <section>
+      <title>Adding a search bar</title>
+
+      <para>We continue to flesh out the functionality of our application.
+      For now, we add search. GTK+ supports this with #GtkSearchEntry and
+      #GtkSearchBar. The search bar is a widget that can slide in from the
+      top to present a search entry.</para>
+
+      <para>We add a toggle button to the header bar, which can be used
+      to slide out the search bar below the header bar.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application7/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>Implementing the search needs quite a few code changes that
+      we are not going to completely go over here. The central piece of
+      the search implementation is a signal handler that listens for
+      text changes in the search entry.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+static void
+search_text_changed (GtkEntry         *entry,
+                     ExampleAppWindow *win)
+{
+  const gchar *text;
+  GtkWidget *tab;
+  GtkWidget *view;
+  GtkTextBuffer *buffer;
+  GtkTextIter start, match_start, match_end;
+
+  text = gtk_entry_get_text (entry);
+
+  if (text[0] == '\0')
+    return;
+
+  tab = gtk_stack_get_visible_child (GTK_STACK (win->stack));
+  view = gtk_bin_get_child (GTK_BIN (tab));
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  /* Very simple-minded search implementation */
+  gtk_text_buffer_get_start_iter (buffer, &start);
+  if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
+                                    &match_start, &match_end, NULL))
+    {
+      gtk_text_buffer_select_range (buffer, &match_start, &match_end);
+      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
+                                    0.0, FALSE, 0.0, 0.0);
+    }
+}
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+
+...
+
+  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
+
+...
+
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>With the search bar, our application now looks like this:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app7.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+    </section>
+
+    <section>
+      <title>Adding a side bar</title>
+
+      <para>As another piece of functionality, we are adding a sidebar,
+      which demonstrates #GtkMenuButton, #GtkRevealer and #GtkListBox.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application8/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>The code to populate the sidebar with buttons for the words
+      found in each file is a little too involved to go into here. But we'll
+      look at the code to add the gears menu.</para>
+
+      <para>As expected by now, the gears menu is specified in a GtkBuilder
+      ui file.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application8/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>To connect the menuitem to the show-words setting, we use
+      a #GAction corresponding to the given #GSettings key.</para>
+
+      <informalexample>
+        <programlisting><![CDATA[
+...
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+
+...
+
+  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
+  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
+  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->gears), menu);
+  g_object_unref (builder);
+
+  action = g_settings_create_action (priv->settings, "show-words");
+  g_action_map_add_action (G_ACTION_MAP (win), action);
+  g_object_unref (action);
+}
+
+...
+        ]]></programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>What our application looks like now:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app8.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+    </section>
+    <section>
+      <title>Properties</title>
+
+      <para>Widgets and other objects have many useful properties.</para>
+
+      <para>Here we show some ways to use them in new and flexible ways,
+      by wrapping them in actions with #GPropertyAction or by binding them
+      with #GBinding.</para>
+
+      <para>To set this up, we add two labels to the header bar in our
+      window template, named @lines_label and @lines, and bind them to
+      struct members in the private struct, as we've seen a couple of times
+      by now.</para>
+
+      <para>We add a new "Lines" menu item to the gears menu, which
+      triggers the show-lines action:</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application9/gears-menu.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>To make this menu item do something, we create a property
+      action for the visible property of the @lines label, and add it to the
+      actions of the window. The effect of this is that the visibility
+      of the label gets toggled every time the action is activated.</para>
+
+      <para>Since we want both labels to appear and disappear together,
+      we bind the visible property of the @lines_label widget to the
+      same property of the @lines widget.</para>
+
+      <informalexample>
+        <programlisting>
+...
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+  ...
+
+  action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible");
+  g_action_map_add_action (G_ACTION_MAP (win), action);
+  g_object_unref (action);
+
+  g_object_bind_property (win->lines, "visible",
+                          win->lines_label, "visible",
+                          G_BINDING_DEFAULT);
+}
+
+...
+        </programlisting>
+        <para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>)</para>
+      </informalexample>
+
+      <para>We also need a function that counts the lines of the currently
+      active tab, and updates the @lines label. See the
+      <ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>
+      if you are interested in the details.</para>
+
+      <para>This brings our example application to this appearance:</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app9.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+    </section>
+    <section>
+      <title>Header bar</title>
+
+      <para>Our application already uses a GtkHeaderBar, but so far it
+      still gets a 'normal' window titlebar on top of that. This is a
+      bit redundant, and we will now tell GTK+ to use the header bar
+      as replacement for the titlebar. To do so, we move it around to
+      be a direct child of the window, and set its type to be titlebar.</para>
+
+      <informalexample>
+        <programlisting><xi:include href="@SRC_DIR@/examples/application10/window.ui" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+      </informalexample>
+
+      <para>A small extra bonus of using a header bar is that we get
+      a fallback application menu for free. Here is how the
+      application now looks, if this fallback is used.</para>
+
+      <informalfigure>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="getting-started-app10.png" format="PNG"/>
+          </imageobject>
+        </mediaobject>
+      </informalfigure>
+
+      <para>If we set up the window icon for our window, the menu button
+      will use that instead of the generic placeholder icon you see
+      here.</para>
+    </section>
+  </section>
+
+  <section>
+    <title>Custom Drawing</title>
+
+    <para>Many widgets, like buttons, do all their drawing themselves. You
+    just tell them the label you want to see, and they figure out what font
+    to use, draw the button outline and focus rectangle, etc. Sometimes, it
+    is necessary to do some custom drawing. In that case, a #GtkDrawingArea
+    might be the right widget to use. It offers a canvas on which you can
+    draw by connecting to the #GtkWidget::draw signal.
+    </para>
+
+    <para>The contents of a widget often need to be partially or fully redrawn,
+    e.g. when another window is moved and uncovers part of the widget, or
+    when the window containing it is resized. It is also possible to explicitly
+    cause part or all of the widget to be redrawn, by calling
+    gtk_widget_queue_draw() or its variants. GTK+ takes care of most of the
+    details by providing a ready-to-use cairo context to the ::draw signal
+    handler.</para>
+
+    <para>The following example shows a ::draw signal handler. It is a bit
+    more complicated than the previous examples, since it also demonstrates
+    input event handling by means of ::button-press and ::motion-notify
+    handlers.</para>
+
+    <informalfigure>
+      <mediaobject>
+        <imageobject>
+          <imagedata fileref="drawing.png" format="PNG"/>
+        </imageobject>
+      </mediaobject>
+    </informalfigure>
+
+    <example id="gtk-getting-started-drawing">
+      <title>Drawing in response to input</title>
+      <para>Create a new file with the following content named example-4.c.</para>
+      <programlisting><xi:include href="@SRC_DIR@/examples/drawing.c" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+    </example>
+    <para>
+      You can compile the program above with GCC using:
+      <literallayout>
+        <literal>gcc `pkg-config --cflags gtk+-4.0` -o example-4 example-4.c `pkg-config --libs gtk+-4.0`</literal>
+      </literallayout>
+    </para>
+  </section>
+
+</chapter>
index e6948491e55870307e3625b08d83fbd6a0ee2aef..66dfc0291f26c6b8a375c0c1afbcedbec89b27a6 100644 (file)
@@ -340,7 +340,6 @@ content_files = [
   'css-overview.xml',
   'css-properties.xml',
   'drawing-model.xml',
-  'getting_started.xml',
   'glossary.xml',
   'gtk4-broadwayd.xml',
   'gtk4-builder-tool.xml',
@@ -372,7 +371,6 @@ content_files = [
 expand_content_files = [
   'compiling.sgml',
   'drawing-model.xml',
-  'getting_started.xml',
   'glossary.xml',
   'input-handling.xml',
   'migrating-2to4.xml',
@@ -383,6 +381,7 @@ expand_content_files = [
 ]
 
 configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
+configure_file(input: 'getting_started.xml.in', output: 'getting_started.xml', configuration: src_dir_conf)
 
 types_conf = configuration_data()
 if os_win32
index 53458a6c90106cc1bc901d13788322593aae8b81..d69068124e970dc77b75966142610c7a7cc9ed0c 100644 (file)
@@ -12,6 +12,9 @@ docpath = join_paths(gtk_datadir, 'gtk-doc', 'html')
 version_conf = configuration_data()
 version_conf.set('GTK_VERSION', meson.project_version())
 
+src_dir_conf = configuration_data()
+src_dir_conf.set('SRC_DIR', meson.source_root())
+
 subdir('gdk')
 subdir('gsk')
 subdir('gtk')